﻿using Microsoft.Win32;
using SharpSoft;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace SignApp
{
    /// <summary>
    /// KeyGenPage.xaml 的交互逻辑
    /// </summary>
    public partial class KeyGenPage : Page
    {
        public KeyGenPage()
        {
            InitializeComponent();
            this.Loaded += KeyGenPage_Loaded;
        }

        void ShowStatus(string msg, StatusType status)
        {
            switch (status)
            {
                case StatusType.None:
                case StatusType.Info:
                    txt_status.Foreground = Brushes.Black;
                    break;
                case StatusType.Success:
                    txt_status.Foreground = Brushes.DarkSeaGreen;
                    break;
                case StatusType.Warnning:
                    txt_status.Foreground = Brushes.Gold;
                    break;
                case StatusType.Error:
                    txt_status.Foreground = Brushes.Orange;
                    break;
                default:
                    break;
            }
            txt_status.Text = msg;
        }
        private void KeyGenPage_Loaded(object sender, RoutedEventArgs e)
        {
            var knames = Enum.GetValues(typeof(RsaKeyType));
            var dic = new Dictionary<RsaKeyType, string>();
            foreach (RsaKeyType item in knames)
            {
                dic.Add(item, Enum.GetName(typeof(RsaKeyType), item));
            }
            cmb_keyTypes.ItemsSource = dic;
            cmb_keyTypes.SelectedValuePath = "Key";
            cmb_keyTypes.DisplayMemberPath = "Value";
            cmb_keyTypes.SelectedIndex = 0;
        }

        private RsaKey storeKey;
        private async void btn_gen_Click(object sender, RoutedEventArgs e)
        {

            var mask = await this.MaskAsync(new TextBlock() { Text = "正在生成...", Foreground = Brushes.White, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center });
            var bt = DateTime.Now;
            txt_status.Foreground = Brushes.LightBlue;
            ShowStatus("正在生成...", StatusType.Info);
            try
            {
                var keytype = (RsaKeyType)cmb_keyTypes.SelectedValue;
                var keysize = (int)nud_keyLen.Value;
                var formatkey = cb_format.IsChecked.GetValueOrDefault();
                var key = await Task.Run(new Func<RsaKey>(delegate
                             {
                                 var key = SharpSoft.Security.RsaKeyGenerate(keytype, keysize, formatkey); 
                                 return key;
                             }));
                ShowStatus($"生成耗时：{(DateTime.Now - bt).TotalSeconds:0.00}秒", StatusType.Success);
                rtf_priKey.Document.Blocks.Clear();
                rtf_priKey.AppendText(key.PrivateKey);
                rtf_pubKey.Document.Blocks.Clear();
                rtf_pubKey.AppendText(key.PublicKey);
                storeKey = key;
            }
            catch (Exception ex)
            {
                ShowStatus("生成失败", StatusType.Error);
                await this.ToastAsync("生成错误", ex.Message, SharpSoft.WPF.Masks.ToastTemplate.ToastType.Error, TimeSpan.FromSeconds(5));
            }
            finally
            {
                mask.Close();
            }
        }


        private async void btn_export_Click(object sender, RoutedEventArgs e)
        {
            if (storeKey == null)
            {
                await this.ToastAsync("导出错误", "请先生成一个RSA密钥。", SharpSoft.WPF.Masks.ToastTemplate.ToastType.Error, TimeSpan.FromSeconds(3));
                return;
            }
            if (string.IsNullOrEmpty(storeKey.PrivateKey) || string.IsNullOrEmpty(storeKey.PublicKey))
            {
                await this.ToastAsync("导出错误", "密钥信息不完整，无法导出。", SharpSoft.WPF.Masks.ToastTemplate.ToastType.Error, TimeSpan.FromSeconds(5));
                return;
            }
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.DefaultExt = "*.txt";
            sfd.AddExtension = true;
            sfd.Title = "导出密钥";
            sfd.Filter = "文本文件(*.txt)|*.txt|所有文件(*.*)|*.*";
            sfd.FileName = $"{DateTime.Now:yyyyMMddHHmmss}";
            sfd.CheckFileExists = false;
            sfd.CheckPathExists = true;
            var result = sfd.ShowDialog();

            bool doubleFile = true;//保存为两个文件
            if (result.GetValueOrDefault())
            {
                var file = sfd.FileName;
                if (doubleFile)
                {
                    var folder = System.IO.Path.GetDirectoryName(file);
                    var filepri = System.IO.Path.Combine(folder,"prikey.txt");
                    using (var fs = new FileStream( filepri, FileMode.Create, FileAccess.Write))
                    {
                        using (var sw = new StreamWriter(fs, new UTF8Encoding(false)))
                        { 
                            sw.Write (storeKey.PrivateKey); 

                        }
                    }
                    var filepub = System.IO.Path.Combine(folder, "pubkey.txt");
                    using (var fs = new FileStream(filepub, FileMode.Create, FileAccess.Write))
                    {
                        using (var sw = new StreamWriter(fs, new UTF8Encoding(false)))
                        {
                            sw.Write(storeKey.PublicKey);

                        }
                    }
                }
                else
                {
                    using (var fs = new FileStream(file, FileMode.Create, FileAccess.Write))
                    {
                        using (var sw = new StreamWriter(fs, new UTF8Encoding(false)))
                        {
                            sw.WriteLine("--------PRIVATE KEY--------");
                            sw.WriteLine(storeKey.PrivateKey);
                            sw.WriteLine("--------PUBLIC KEY--------");
                            sw.WriteLine(storeKey.PublicKey);

                        }
                    }
                }

                await this.ToastAsync("导出完成", $"已导出到：[{file}]", SharpSoft.WPF.Masks.ToastTemplate.ToastType.Success, TimeSpan.FromSeconds(5));
            }
        }
    }
}
